package zcxn.microService.dofile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;

public class PackageMicroService {
	/**
	 * 1、 将文件从目标文件组成List<File> 
	 * 2、 copy 目标文件中的List<File> 到F 盘的根目录中 
	 * 3、将目标文件组成一个List<File> 
	 * 4、将list<File>文件打包为 xxxxx.sh.tg 
	 * 5、将xxxx.sh.tg 文件压缩为xxxxx.sh.tgz
	 * 6、将生成好的xxxx.sh.tgz 文件copy到原来的目录中
	 * 7、删除F 盘目录中的中间产物文件(垃圾回收)
	 * 
	 * 
	 */
	
	/**
	 * 封装了 打包的方法
	 * @param service
	 * @param agentId
	 */
	public void packageService(String serviceName,String agentId) {
		List<File> intoFileDir = this.intoFileDir(serviceName, agentId);
		int count=this.deleteFiles(intoFileDir);
		System.out.println("F 中已经删除的文件："+count);
	} 
	
	/**
	 * 删除中间产物文件
	 * @param filesInF
	 * @return
	 */
    public int deleteFiles(List<File> filesInF) {
    	System.gc();
    	Iterator<File> iterator = filesInF.iterator();
		System.out.println("F 盘中要删除的文件个数 ："+filesInF.size());
		int count = 0;
		while (iterator.hasNext()) {
			File next = iterator.next();
			boolean delete = next.delete();
			if (delete == true) {
				count++;
			}
			System.out.println(next.getName() + "==========" + delete);
			if (count == 5) {
				System.out.println("copy Finish and delete Files");
			}
		}
		return count;
    }
	/**
	 * 将文件copy 到对应的目录中去 .删除之前F 盘中 文件
	 * 
	 * @param serviceName
	 * @param gridId
	 */
	public List<File> intoFileDir(String serviceName, String gridId) {
		// 将要打包的文件组成一个list' 集合
		List<File> srcFiles = getToPackFiles(serviceName, gridId);
		// 将每一个文件copy 到F 盘的更目录下
		for (int i = 0; i < srcFiles.size(); i++) {
			this.copyFile(srcFiles.get(i), srcFiles.get(i).getName());
		}
		// 得到F盘 根目录下 需要打包的文件
		List<File> filesInF = getFilesInF(serviceName, gridId);
		File pack = pack(filesInF, new File("F:" + File.separator + serviceName.concat(".sh.tg")));
		File compress = compress(pack);
		copyFile(compress,
				"DataLogger_build" + File.separator + "GridId".concat(gridId) + File.separator + compress.getName());
		filesInF.add(pack);
		filesInF.add(compress);
		return filesInF;
	}

	/**
	 * 将F盘 中需要打包的文件 组成一个 list<File>
	 * 
	 * @param serviceName
	 * @param gridId
	 * @return
	 */
	public static List<File> getFilesInF(String serviceName, String gridId) {
		String rootPath = "F:" + File.separator;
		File erFile = new File(rootPath + serviceName);

		File startFile = new File(rootPath + serviceName.concat(".sh"));
		File configFile = new File(rootPath + "config".concat(gridId).concat(".yaml"));
		List<File> files = new ArrayList<File>();
		files.add(erFile);
		files.add(startFile);
		files.add(configFile);
		return files;
	}

	/**
	 * 将目标文件压缩为 xxxx.sh.tgz
	 * 
	 * @param source
	 * @return
	 */
	public static File compress(File source) {
		File target = new File(source.getName().concat("z"));
		FileInputStream in = null;
		GZIPOutputStream out = null;
		try {
			in = new FileInputStream(source);
			out = new GZIPOutputStream(new FileOutputStream(target));
			byte[] array = new byte[1024];
			int number = -1;
			while ((number = in.read(array, 0, array.length)) != -1) {
				out.write(array, 0, number);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
					return null;
				}
			}

			if (out != null) {
				try {
					out.close();
					out.flush();
				} catch (IOException e) {
					e.printStackTrace();
					return null;
				}
			}
		}
		return target;
	}

	/**
	 * 将list文件打包 一个目标文件
	 * 
	 * @param sources
	 * @param target
	 * @return
	 */
	public static File pack(List<File> sources, File target) {
		FileOutputStream out = null;
		try {
			out = new FileOutputStream(target);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		TarArchiveOutputStream os = new TarArchiveOutputStream(out);
		for (File file : sources) {
			try {
				System.out.println(file.getName());

				os.putArchiveEntry(new TarArchiveEntry(file));
				IOUtils.copy(new FileInputStream(file), os);
				os.closeArchiveEntry();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (os != null) {
			try {
				os.close();
				out.close();
				os.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return target;
	}

	/**
	 * 2、将需要打包的单个文件copy到f盘的根目录
	 * 
	 * @param inFile
	 */
	public void copyFile(File inFile, String fileName) {
		// 输出文件路径
		String outPath = "F:" + File.separator + fileName;
		File outFile = new File(outPath);
		// 判断输出文件路径是否存在，不存在 就创建
		if (!outFile.exists()) {
			outFile.getParentFile().mkdirs();
			System.out.println("文件不存在");
		} else {
			outFile.delete();
			System.out.println("目标文件存在已经被删除");
		}
		InputStream is = null;
		OutputStream os = null;
		int tmp = 0;
		byte[] content = new byte[1024];
		try {
			is = new FileInputStream(inFile);
			os = new FileOutputStream(outFile);
			try {
				while (((tmp = is.read(content)) != -1)) {
					os.write(content, 0, tmp);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(String.format("目标文件存在 ： %s", outFile.getPath()));
		System.out.println(String.format("From : %s >>>  To: %s", inFile.getPath(), outFile.getPath()));
		
		
		
		try {
			is.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			os.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			os.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 1、需要打包的文件 组成放在一个list 中
	 * 
	 * @param serviceName
	 * @param gridId
	 * @return
	 */
	public static List<File> getToPackFiles(String serviceName, String gridId) {
		String rootPath = "F:" + File.separator + "DataLogger_build" + File.separator + "GridId".concat(gridId)
				+ File.separator;
		File erFile = new File(rootPath + serviceName);
		File startFile = new File(rootPath + serviceName.concat(".sh"));
		File configFile = new File(rootPath + "config".concat(gridId).concat(".yaml"));

		List<File> files = new ArrayList<File>();
		files.add(erFile);
		files.add(startFile);
		files.add(configFile);
		return files;
	}

	/**
	 * 查询目录下的所有文件 (未用)
	 * 
	 * @param sources
	 * @param target
	 * @return
	 */
	public static List<File> getFiles(String path) {
		File root = new File(path);
		List<File> files = new ArrayList<File>();
		if (!root.isDirectory()) {
			files.add(root);
		} else {
			File[] subFiles = root.listFiles();
			for (File f : subFiles) {
				files.addAll(getFiles(f.getAbsolutePath()));
			}
		}
		return files;
	}

}
